package com.devunion.bogdan.view.project.dialogs;

import com.devunion.bogdan.view.util.i18n;
import com.devunion.bogdan.view.util.DialogHelper;
import com.devunion.bogdan.view.util.ComponentFactory;

import javax.swing.*;
import javax.swing.event.DocumentListener;
import javax.swing.event.DocumentEvent;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.File;

import org.apache.commons.lang.StringUtils;

/**
 * @author Viktar Liaskovich
 */
public class TextEntryDialog extends JDialog {
    private JTextComponent jTextComponentFileName;
    private JLabel jLabelMessage;
    private JLabel jLabelWarning;

    private File currentDir;
    private FileNameTransformer fileNameTransformer;
    private ComponentFactory.OkCancelPanel panelButtonOkCancel;

    public TextEntryDialog(Frame owner) throws HeadlessException {
        super(owner);
        init();
        pack();
    }

    public void setFileNameTransformer(FileNameTransformer fileNameTransformer) {
        this.fileNameTransformer = fileNameTransformer;
    }

    private void init() {
        jTextComponentFileName = new JTextField();

        jLabelMessage = new JLabel();
        jLabelWarning = new JLabel(i18n.getString("TextEntryDialog.EnterFileName"));
        jLabelWarning.setForeground(Color.RED);

        panelButtonOkCancel = ComponentFactory.createPanelButtonOkCancel(this,
                new ComponentFactory.ActionHandler() {
                    public void execute() {
                        TextEntryDialog.this.setVisible(false);
                    }
                },

                new ComponentFactory.ActionValidator() {
                    public boolean validate() {

                        String filename = getText();

                        if (filename == null) {
                            setWarningText(i18n.getString("TextEntryDialog.BlankText"));
                            jTextComponentFileName.grabFocus();

                            updateWarningLabel(true);

                            return false;
                        }

                        boolean isAlreadyExists = new File(currentDir, filename).exists();

                        if (isAlreadyExists) {
                            setWarningText(i18n.getString("TextEntryDialog.AlreadyExist"));
                            jTextComponentFileName.grabFocus();
                        }

                        updateWarningLabel(isAlreadyExists);

                        return !isAlreadyExists;
                    }
                }
        );

        panelButtonOkCancel.getButtonOk().setEnabled(false);

        getContentPane().setLayout(new GridBagLayout());

        DialogHelper.placeComponent(getContentPane(), jLabelMessage,
                0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                15, 10, 10, 10);

        jTextComponentFileName.setPreferredSize(new Dimension(250, jTextComponentFileName.getPreferredSize().height));
        jTextComponentFileName.getDocument().addDocumentListener(new DocumentListener() {
            public void insertUpdate(DocumentEvent e) {
                boolean isGoodLength = e.getDocument().getLength() != 0;
                panelButtonOkCancel.getButtonOk().setEnabled(isGoodLength);

                if (!isGoodLength) {
                    setWarningText(i18n.getString("TextEntryDialog.EnterFileName"));
                }

                updateWarningLabel(!isGoodLength);
            }

            public void removeUpdate(DocumentEvent e) {
                boolean isGoodLength = e.getDocument().getLength() != 0;
                panelButtonOkCancel.getButtonOk().setEnabled(isGoodLength);

                if (!isGoodLength) {
                    setWarningText(i18n.getString("TextEntryDialog.EnterFileName"));
                }

                updateWarningLabel(!isGoodLength);
            }

            public void changedUpdate(DocumentEvent e) {
                boolean isGoodLength = e.getDocument().getLength() != 0;
                panelButtonOkCancel.getButtonOk().setEnabled(isGoodLength);

                if (!isGoodLength) {
                    setWarningText(i18n.getString("TextEntryDialog.EnterFileName"));
                }

                updateWarningLabel(!isGoodLength);
            }
        });

        DialogHelper.placeComponent(getContentPane(), jTextComponentFileName,
                0, 1, 1, 1, 1.0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                0, 10, 10, 10);

        DialogHelper.placeComponent(getContentPane(), Box.createVerticalGlue(),
                0, 2, 1, 1, 0, 1.0, GridBagConstraints.SOUTH, GridBagConstraints.BOTH,
                0, 0, 0, 0);

        DialogHelper.placeComponent(getContentPane(), jLabelWarning,
                0, 3, 1, 1, 0, 0.0, GridBagConstraints.NORTHEAST, GridBagConstraints.HORIZONTAL,
                0, 10, 10, 10);

        DialogHelper.placeComponent(getContentPane(), panelButtonOkCancel,
                0, 4, 1, 1, 0, 0, GridBagConstraints.SOUTH, GridBagConstraints.HORIZONTAL,
                0, 10, 10, 15);

        addComponentListener(new ComponentAdapter() {
            public void componentShown(ComponentEvent e) {
                jTextComponentFileName.setText("");
                jTextComponentFileName.requestFocusInWindow();
            }
        });
    }

    private void updateWarningLabel(boolean visible) {
        jLabelWarning.setForeground(visible ? Color.RED : getContentPane().getBackground());
    }

    public void setMessage(String msg) {
        jLabelMessage.setText(msg);
    }

    public String getText() {
        String text = jTextComponentFileName.getText();

        if (StringUtils.isBlank(text)) {
            return null;
        }

        if (fileNameTransformer == null) {
            return text.trim();
        }

        return fileNameTransformer.transform(text.trim());
    }

    public void setCurrentDir(File dir) {
        currentDir = dir;
    }

    private void setWarningText(String text) {
        if (!jLabelWarning.getText().equals(text)) {
            jLabelWarning.setText(text);
        }
    }

    public ActionResult getActionResult() {
        return panelButtonOkCancel.getActionResult();
    }
}
